#ifndef PARSER_H
#define PARSER_H

#include <sstream>

#include "Exceptions/UnexpectedEndOfFile.h"
#include "Interfaces/IProgramParser.h"

#include "Utility/ProgramParserFunctions.h"
#include "FileOperation.h"
#include "ParserObject.h"
#include "Type.h"




class ProgramParser : public IProgramParser, public ProgramParserFunctions {
private:
	// properties
	int parsePosition;
	std::string rawData;
	static std::stringstream debugOutput;
	std::vector<ParserObject> processedData;
	std::vector<const char*> dataInfo;
protected:
	unsigned int whereCurrentLineEnds();
	bool nextLineExists();
	std::string getNextLine();

	bool isAssign(std::string line);
	bool isCall(std::string line);
	bool isProcedure(std::string line);
	bool isWhile(std::string line);
	bool isIfThen(std::string line);
	bool isElse(std::string line);
	bool isClosure(std::string line);
	ParserObject parseAssign(std::string line);
	ParserObject parseCall(std::string line);
	ParserObject parseProcedure(std::string line);
	ParserObject parseWhile(std::string line);
	ParserObject parseIfThen(std::string line);
	ParserObject parseElse(std::string line);
	ParserObject parseClosure(std::string line);
	ParserObject parseError(std::string line);
	ParserObject processLine(std::string line);
public:
	// properties
	static int programLevel;
	static const char* keywords[];

	// constructors
	ProgramParser(std::string fileName);
	ProgramParser(const char* contents);
	ProgramParser();

	// public methods
	void parse();

	// accessors
	std::string getDebugOutput();
	std::string getRawData();
	ParserObject &operator[](unsigned int index);
	unsigned int size();
};

#endif